#include "SipSessionBase.hpp"

#include "SipClnTransaction.hpp"
#include "SipSrvTransaction.hpp"
#include "SipDialog.hpp"
#include "SipGDService.hpp"

namespace wtsip{

#define FailedReason(r, c) c

int CSipSessionBase::s_ReasonCode[] = {
    FailedReason(Trying, 100),
    FailedReason(RespseOK, 200),
    FailedReason(Error, 400),
    FailedReason(UnAuth, 407),
    FailedReason(Rejected, 403),
    FailedReason(NonUser, 404),
    FailedReason(UnAuth, 407),
    FailedReason(ReqTimeout, 408),
    FailedReason(NonTrans, 481),
    FailedReason(ReqEnded, 487)
};

#undef FailedReason


CSipSessionBase::CSipSessionBase(CSipGDService& srv, CSipClnTransaction& clntran):
m_clnTran(&clntran), m_srvTran(0), m_dialog(0), m_service(srv)
{
    m_id = clntran.getTid();
    m_RemoteUri = clntran.getRequest().header(h_To).uri();
    m_LocalUri = clntran.getRequest().header(h_From).uri();
}


CSipSessionBase::CSipSessionBase(CSipGDService& srv, CSipSrvTransaction& srvtran):
m_clnTran(0), m_srvTran(&srvtran), m_dialog(0), m_service(srv)
{
    m_id = srvtran.getTid();
    m_RemoteUri = srvtran.getRequest().header(h_From).uri();
    m_LocalUri = srvtran.getRequest().header(h_To).uri();
}


CSipSessionBase::CSipSessionBase(CSipGDService& srv, CSipDialogBase& dlg):
m_clnTran(0), m_srvTran(0), m_dialog(&dlg), m_service(srv)
{
    m_id = dlg.getCallID();
    m_RemoteUri = dlg.getRemoteNameAddr().uri();
    m_LocalUri = dlg.getLocalNameAddr().uri();
}


CSipSessionBase::~CSipSessionBase(){}


const resip::Data& CSipSessionBase::getID(){
    return m_id;
}


const resip::Uri& CSipSessionBase::getRemoteUri(){
    return m_RemoteUri;
}


const resip::Uri& CSipSessionBase::getLocalUri(){
    return m_LocalUri;
}


bool CSipSessionBase::registerHandle(CSipSessionHandle* handle){
    if (handle){
        m_handleList.push_back(handle);
    }
    return true;
}


bool CSipSessionBase::unregisterHandle(CSipSessionHandle* handle){
    if (handle){
        m_handleList.remove(handle);
    }
    return true;
}


bool CSipSessionBase::destroy()
{
    this->onDestroy();
    handleDestroy();
    m_service.destroyDlgSession(m_id);
    return true;
}


//////////////////////// static methods  //////////////

resip::Mime& CSipSessionBase::getMimeType(){
    static resip::Mime mimeType(APPLICATION, DDCP_XML);
    return mimeType;
}


CSipSessionBase::EFailReason CSipSessionBase::getReasonbyCode(int code){
    typedef CSipSessionBase::EFailReason EReason;
    EReason reason = CSipSessionBase::Unknown;
    for (int i = 0; i < CSipSessionBase::MAXREASON; i++){
        if (s_ReasonCode[i] == code){
            reason = (EReason)i;
            break;
        }
    }
    return reason;
}


int CSipSessionBase::getCodebyReason(CSipSessionBase::EFailReason reason){
    return s_ReasonCode[reason];
}

//////////////////////  handle list method  /////////////////////

bool CSipSessionBase::handleTrying(SipMessage& msg)
{
    std::list<CSipSessionHandle*>::iterator it = m_handleList.begin();
    for (; it != m_handleList.end(); it++){
        (*it)->onTrying(msg, *this);
    }
    return true;
}


bool CSipSessionBase::handleSuccess(SipMessage& msg)
{
    std::list<CSipSessionHandle*>::iterator it = m_handleList.begin();
    for (; it != m_handleList.end(); it++){
        (*it)->onSuccess(msg, *this);
    }
    return true;
}


bool CSipSessionBase::handleFailed(SipMessage& msg)
{
    std::list<CSipSessionHandle*>::iterator it = m_handleList.begin();
    for (; it != m_handleList.end(); it++)
    {
        (*it)->onFailed(msg, *this);
    }
    return true;
}


bool CSipSessionBase::handleDestroy(){
    std::list<CSipSessionHandle*>::iterator it = m_handleList.begin();
    for (; it != m_handleList.end(); it++)
    {
        (*it)->onDestroy(*this);
    }
    return true;
}


} //namespace


